﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace GMusicBox.Core
{
    public class Lyric
    {
        public Lyric()
        {
            Texts = new List<string>();
            Times = new List<double>();
        }

        public Lyric(string filename) : this()
        {
            GetLyric(filename);
        }

        string source = "";

        [Browsable(false)]
        public List<string> Texts { get; set; }

        [Browsable(false)]
        public List<double> Times { get; set; }

        [DefaultValue("")]
        public string Source
        {
            get { return source; }
            set
            {
                source = value;
                GetLyric(source);
            }
        }

        public bool IsNull { get; set; }

        public void GetLyric(string source)
        {
            GetLyric(source, Encoding.Default);
        }

        public void GetLyric(string source, Encoding encoding)
        {
            this.source = source;
            Texts.Clear(); Times.Clear();
            string fs = File.ReadAllText(source, encoding).Trim();
            Regex r = new Regex(@"\[[0-9]*:[0-9]*.[0-9]*\]");
            MatchCollection mc = r.Matches(fs);

            Times.Add(0); Texts.Add("");
            for (int i = 0; i < mc.Count; i++)
            {
                Times.Add(GetNumberTime(mc[i].Value.Substring(1, 8)));
                if (i != 0 && mc[i - 1].Index + mc[i - 1].Length != mc[i].Index)
                {
                    int s = mc[i - 1].Index + mc[i - 1].Length;
                    int len = mc[i].Index - s;

                    while (Texts.Count + 1 != Times.Count) 
                        Texts.Add(fs.Substring(s, len).Trim());
                }

                if (i == mc.Count - 1) 
                    while (Texts.Count != Times.Count) 
                        Texts.Add(fs.Substring(mc[i].Index + mc[i].Length).Trim());
            }

            for (int i = 0; i < Times.Count; i++)
            {
                for (int j = i + 1; j < Times.Count; j++)
                {
                    if (Times[i] > Times[j])
                    {
                        double t = Times[i]; string s = Texts[i];
                        Times[i] = Times[j]; Texts[i] = Texts[j];
                        Times[j] = t; Texts[j] = s;
                    }
                }
            }
            Times.Add(6039); Texts.Add("");
        }

        private double GetNumberTime(string s)
        {
            try
            {
                string[] ss = s.Split('.', ':');
                int t, t1, t2;
                if (!int.TryParse(ss[0], out t)) return 0;
                if (!int.TryParse(ss[1], out t1)) return 0;
                if (!int.TryParse(ss[2], out t2)) return 0;
                t *= 60;
                t1 = t + int.Parse(ss[1]);
                return t1 + t2 / 100.0;
            }
            catch { }
            return 0;
        }

        public void Offset(double offset)
        {
            for (int i = 1; i < Times.Count; i++)
                Offset(i, offset);
        }

        public void Offset(int index, double offset)
        {
            Times[index] += offset;
        }
    }
}
